package com.ct.application.shipping.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ct.application.commons.vo.StatusRequest;
import com.ct.application.shipping.model.po.ChuanYuanDiaoLingSavePO;
import com.ct.application.shipping.model.po.ChuanYuanDiaoLingSearchPO;
import com.ct.application.shipping.model.po.LiuChengDingYiBuZhouSavePO;
import com.ct.application.shipping.model.po.LiuChengYeWuSavePO;
import com.ct.application.shipping.model.vo.ChuanYuanDiaoLingVO;
import com.ct.application.shipping.service.*;
import com.ct.repository.commons.BaseServiceImpl;
import com.ct.shipping.mapper.ChuanYuanDiaoLingMapper;
import com.ct.shipping.orm.*;
import com.ct.utils.date.DateUtils;
import com.ct.utils.threadlocal.UserThreadLocal;
import com.ct.utils.valid.ValidatorUtil;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 船员调令 服务实现类
 * </p>
 *
 * @author carlo
 */
@Service
public class ChuanYuanDiaoLingServiceImpl extends BaseServiceImpl<ChuanYuanDiaoLingMapper, ChuanYuanDiaoLingDO>
        implements ChuanYuanDiaoLingService {

    @Resource
    private ChuanYuanKuService chuanYuanKuService;
    @Resource
    private ShenPiDanHaoService shenPiDanHaoService;
    @Resource
    private LiuChengDingYiService liuChengDingYiService;
    @Resource
    private LiuChengYeWuService liuChengYeWuService;
    @Resource
    private ChuanYuanDiaoPeiService chuanYuanDiaoPeiService;

    /**
     * 查询分页列表
     */
    @Override
    public Page<ChuanYuanDiaoLingVO> findChuanYuanDiaoLing(ChuanYuanDiaoLingSearchPO searchPO) {
        LambdaQueryWrapper<ChuanYuanDiaoLingDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.eq(!("全选".equals(searchPO.getChuanBoMing())), ChuanYuanDiaoLingDO::getSuoZaiChuanBo, searchPO.getChuanBoMing())
                .eq(!("全选".equals(searchPO.getZhiWei())), ChuanYuanDiaoLingDO::getZhiWei, searchPO.getZhiWei())
                .eq(!("全选".equals(searchPO.getShenPiZhuangTai())), ChuanYuanDiaoLingDO::getShenPiZhuangTai, searchPO.getShenPiZhuangTai());

        if (StringUtils.isNotEmpty(searchPO.getKeyword())) {
            lambdaQueryWrapper.and(w -> {
                w.like(ChuanYuanDiaoLingDO::getXiaChuanYuanMing, searchPO.getKeyword())
                        .or()
                        .like(ChuanYuanDiaoLingDO::getXiaChuanYuanShenFenHao, searchPO.getKeyword())
                        .or()
                        .like(ChuanYuanDiaoLingDO::getShangChuanYuanMing, searchPO.getKeyword())
                        .or()
                        .like(ChuanYuanDiaoLingDO::getShangChuanYuanShenFenHao, searchPO.getKeyword());
            });
        }
        if (StringUtils.isNotEmpty(searchPO.getStartDate()) && StringUtils.isNotEmpty(searchPO.getEndDate())) {
            lambdaQueryWrapper.ge(ChuanYuanDiaoLingDO::getShangXiaChuanRiQi, DateUtils.stringToDate(searchPO.getStartDate()))
                    .le(ChuanYuanDiaoLingDO::getShangXiaChuanRiQi, DateUtils.stringToDate(searchPO.getEndDate()));
        }

        lambdaQueryWrapper.orderByDesc(ChuanYuanDiaoLingDO::getCreateTime);
        Page<ChuanYuanDiaoLingDO> page = new Page<>(searchPO.getPageNo(), searchPO.getPageSize());
        Page<ChuanYuanDiaoLingDO> page1 = this.page(page, lambdaQueryWrapper);
        return tranferPageBo(page1, ChuanYuanDiaoLingVO.class);
    }


    /**
     * 保存
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveChuanYuanDiaoLing(ChuanYuanDiaoLingSavePO savePO) {
        savePO.setId(null); //新增不需要id

        ChuanYuanDiaoLingDO chuanYuanDiaoLingDO = tranferBo(savePO, ChuanYuanDiaoLingDO.class);
        if (Objects.nonNull(chuanYuanDiaoLingDO)) {
            // 调令类型。1:轮换船员 2:仅有上船 3:仅有下船
            Integer leiXing = savePO.getLeiXing();
            if (leiXing == 1) {     // 调令类型。1:轮换船员
                //下船船员id
                Long xiaChuanYuanId = savePO.getXiaChuanYuanId();
                ChuanYuanKuDO xiaChuanYuan = chuanYuanKuService.getById(xiaChuanYuanId);
                if (xiaChuanYuan == null) {
                    throw new RuntimeException("查无此下船船员数据");
                }
                Long xiaChuanYuanCount = this.lambdaQuery()
                        .eq(ChuanYuanDiaoLingDO::getXiaChuanYuanId, xiaChuanYuanId)
                        .eq(ChuanYuanDiaoLingDO::getShenPiZhuangTai, "审批中")
                        .count();
                if (xiaChuanYuanCount > 0) {
                    throw new RuntimeException("此下船船员已有调令正在审批中");
                }

                //上船船员id
                Long shangChuanYuanId = savePO.getShangChuanYuanId();
                ChuanYuanKuDO shangChuanYuan = chuanYuanKuService.getById(shangChuanYuanId);
                if (shangChuanYuan == null) {
                    throw new RuntimeException("查无此上船船员数据");
                }
                Long shangChuanYuanCount = this.lambdaQuery()
                        .eq(ChuanYuanDiaoLingDO::getShangChuanYuanId, shangChuanYuanId)
                        .eq(ChuanYuanDiaoLingDO::getShenPiZhuangTai, "审批中")
                        .count();
                if (shangChuanYuanCount > 0) {
                    throw new RuntimeException("此上船船员已有调令正在审批中");
                }

                chuanYuanDiaoLingDO.setXiaChuanYuanId(xiaChuanYuan.getId());
                chuanYuanDiaoLingDO.setXiaChuanYuanMing(xiaChuanYuan.getXingMing());
                chuanYuanDiaoLingDO.setXiaChuanYuanShenFenHao(xiaChuanYuan.getShenFenHao());
                chuanYuanDiaoLingDO.setXiaChuanYuanShouJiHao(xiaChuanYuan.getShouJiHao());
                chuanYuanDiaoLingDO.setShangChuanYuanId(shangChuanYuan.getId());
                chuanYuanDiaoLingDO.setShangChuanYuanMing(shangChuanYuan.getXingMing());
                chuanYuanDiaoLingDO.setShangChuanYuanShenFenHao(shangChuanYuan.getShenFenHao());
                chuanYuanDiaoLingDO.setShangChuanYuanShouJiHao(shangChuanYuan.getShouJiHao());
            } else if (leiXing == 2) {  // 调令类型。 2:仅有上船
                //上船船员id
                Long shangChuanYuanId = savePO.getShangChuanYuanId();
                ChuanYuanKuDO shangChuanYuan = chuanYuanKuService.getById(shangChuanYuanId);
                if (shangChuanYuan == null) {
                    throw new RuntimeException("查无此上船船员数据");
                }
                Long shangChuanYuanCount = this.lambdaQuery()
                        .eq(ChuanYuanDiaoLingDO::getShangChuanYuanId, shangChuanYuanId)
                        .eq(ChuanYuanDiaoLingDO::getShenPiZhuangTai, "审批中")
                        .count();
                if (shangChuanYuanCount > 0) {
                    throw new RuntimeException("此上船船员已有调令正在审批中");
                }

                chuanYuanDiaoLingDO.setShangChuanYuanId(shangChuanYuan.getId());
                chuanYuanDiaoLingDO.setShangChuanYuanMing(shangChuanYuan.getXingMing());
                chuanYuanDiaoLingDO.setShangChuanYuanShenFenHao(shangChuanYuan.getShenFenHao());
                chuanYuanDiaoLingDO.setShangChuanYuanShouJiHao(shangChuanYuan.getShouJiHao());
            } else if (leiXing == 3) {  // 调令类型。 3:仅有下船
                //下船船员id
                Long xiaChuanYuanId = savePO.getXiaChuanYuanId();
                ChuanYuanKuDO xiaChuanYuan = chuanYuanKuService.getById(xiaChuanYuanId);
                if (xiaChuanYuan == null) {
                    throw new RuntimeException("查无此下船船员数据");
                }
                Long xiaChuanYuanCount = this.lambdaQuery()
                        .eq(ChuanYuanDiaoLingDO::getXiaChuanYuanId, xiaChuanYuanId)
                        .eq(ChuanYuanDiaoLingDO::getShenPiZhuangTai, "审批中")
                        .count();
                if (xiaChuanYuanCount > 0) {
                    throw new RuntimeException("此下船船员已有调令正在审批中");
                }
                chuanYuanDiaoLingDO.setXiaChuanYuanId(xiaChuanYuan.getId());
                chuanYuanDiaoLingDO.setXiaChuanYuanMing(xiaChuanYuan.getXingMing());
                chuanYuanDiaoLingDO.setXiaChuanYuanShenFenHao(xiaChuanYuan.getShenFenHao());
                chuanYuanDiaoLingDO.setXiaChuanYuanShouJiHao(xiaChuanYuan.getShouJiHao());
            }

            LocalDate shangChuanDate = new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            int nian = shangChuanDate.getYear();
            int yue = shangChuanDate.getMonthValue();
            ShenPiDanHaoDO danHaoDO = shenPiDanHaoService.lambdaQuery()
                    .eq(ShenPiDanHaoDO::getNian, String.valueOf(nian))
                    .eq(ShenPiDanHaoDO::getYue, String.valueOf(yue))
                    .eq(ShenPiDanHaoDO::getLeiXing, "调令单")
                    .last(" limit 1 ")
                    .one();
            if (danHaoDO != null) {
                long xinHaoMa = danHaoDO.getHaoMa() + 1;
                chuanYuanDiaoLingDO.setDiaoLingDanHao(nian + "" + String.format("%02d", yue) + "" + String.format("%04d", xinHaoMa));

                ShenPiDanHaoDO danHaoUpdate = new ShenPiDanHaoDO();
                danHaoUpdate.setId(danHaoDO.getId());
                danHaoUpdate.setHaoMa(xinHaoMa);
                danHaoUpdate.updateById();
            } else {
                danHaoDO = new ShenPiDanHaoDO();
                danHaoDO.setSystemId(UserThreadLocal.get().getSystemId());
                danHaoDO.setSystemName(UserThreadLocal.get().getSystemName());
                danHaoDO.setNian(String.valueOf(nian));
                danHaoDO.setYue(String.valueOf(yue));
                danHaoDO.setHaoMa(1L);
                danHaoDO.setLeiXing("调令单");
                danHaoDO.insert();
                chuanYuanDiaoLingDO.setDiaoLingDanHao(nian + "" + String.format("%02d", yue) + "" + "0001");
            }
            chuanYuanDiaoLingDO.setShenPiZhuangTai("审批中");
            chuanYuanDiaoLingDO.setShangXiaChuanRiQi(DateUtils.stringToDate(savePO.getShangXiaChuanRiQi()));
            chuanYuanDiaoLingDO.setSystemId(UserThreadLocal.get().getSystemId());
            chuanYuanDiaoLingDO.setSystemName(UserThreadLocal.get().getSystemName());
            boolean save = this.save(chuanYuanDiaoLingDO);
            if (save) {
                LiuChengDingYiDO liuChengDingYiDO = liuChengDingYiService.lambdaQuery()
                        .eq(LiuChengDingYiDO::getLiuChengLeiXing, "船员调令")
                        .like(LiuChengDingYiDO::getChuanBoMing, chuanYuanDiaoLingDO.getSuoZaiChuanBo())
                        .like(LiuChengDingYiDO::getZhiWeiMing, chuanYuanDiaoLingDO.getZhiWei())
                        .orderByDesc(LiuChengDingYiDO::getId)
                        .last(" limit 1 ").one();
                if (liuChengDingYiDO == null) {
                    liuChengDingYiDO = liuChengDingYiService.lambdaQuery()
                            .eq(LiuChengDingYiDO::getLiuChengLeiXing, "船员调令")
                            .eq(LiuChengDingYiDO::getChuanBoMing, "全部")
                            .eq(LiuChengDingYiDO::getZhiWeiMing, "全部")
                            .orderByDesc(LiuChengDingYiDO::getId)
                            .last(" limit 1 ").one();
                    if (liuChengDingYiDO == null) {
                        throw new RuntimeException("所选的船舶和职位找不到匹配的流程，无法发起流程");
                    }
                }
                //流程步骤对象数据
                String buZhouShuJu = liuChengDingYiDO.getBuZhouShuJu();
                List<LiuChengDingYiBuZhouSavePO> buZhouList = JSONArray.parseArray(buZhouShuJu, LiuChengDingYiBuZhouSavePO.class);
                for (int i = 0; i < buZhouList.size(); i++) {
                    LiuChengDingYiBuZhouSavePO buZhou = buZhouList.get(i);
                    LiuChengYeWuDO liuChengYeWuDO = new LiuChengYeWuDO();
                    liuChengYeWuDO.setLiuChengLeiXing("船员调令");
                    liuChengYeWuDO.setYeWuId(chuanYuanDiaoLingDO.getId());
                    liuChengYeWuDO.setLiuChengDingYiId(liuChengDingYiDO.getId());
                    liuChengYeWuDO.setJueSeId(buZhou.getJueSeId());
                    liuChengYeWuDO.setJueSeMing(buZhou.getJueSeMing());
                    liuChengYeWuDO.setJieDianMing(buZhou.getJieDianMing());
                    liuChengYeWuDO.setJieDianCaoZuo("");
                    liuChengYeWuDO.setShenPiYiJian("");
                    liuChengYeWuDO.setShiFouShenPi("否");
                    liuChengYeWuDO.setShenPiZhuangTai("审批中");
                    liuChengYeWuDO.setShiFouZuiHouJieDian("否");
                    if (i == (buZhouList.size() - 1)) {
                        liuChengYeWuDO.setShiFouZuiHouJieDian("是");
                    }
                    liuChengYeWuDO.insert();
                }

                /*找到船员调配的数据，设置调令参数*/
                //调令类型。1:轮换船员 2:仅有上船 3:仅有下船
                if (leiXing == 1 || leiXing == 3) {
                    ChuanYuanDiaoPeiDO chuanYuanDiaoPeiDO = chuanYuanDiaoPeiService.lambdaQuery()
                            .eq(ChuanYuanDiaoPeiDO::getChuanBoMing, chuanYuanDiaoLingDO.getSuoZaiChuanBo())
                            .eq(ChuanYuanDiaoPeiDO::getZhiWei, chuanYuanDiaoLingDO.getZhiWei())
                            .eq(ChuanYuanDiaoPeiDO::getZaiChuanChuanYuanId, chuanYuanDiaoLingDO.getXiaChuanYuanId())
                            .last(" limit 1 ")
                            .one();
                    if (chuanYuanDiaoPeiDO != null) {
                        chuanYuanDiaoPeiService.lambdaUpdate()
                                .set(ChuanYuanDiaoPeiDO::getDiaoLingCanShu, JSONObject.toJSONString(chuanYuanDiaoLingDO))
                                .eq(ChuanYuanDiaoPeiDO::getId,chuanYuanDiaoPeiDO.getId())
                                .update();
                    }
                }
            }
        }
        return true;
    }


    /**
     * 查看调令信息
     */
    @Override
    public ChuanYuanDiaoLingVO getChuanYuanDiaoLing(Long id) {
        ChuanYuanDiaoLingDO chuanYuanDiaoLingDO = getById(id);
        ChuanYuanDiaoLingVO chuanYuanDiaoLingVO = tranferBo(chuanYuanDiaoLingDO, ChuanYuanDiaoLingVO.class);
        List<LiuChengYeWuDO> liuChengYeWuList = liuChengYeWuService.lambdaQuery()
                .eq(LiuChengYeWuDO::getLiuChengLeiXing, "船员调令")
                .eq(LiuChengYeWuDO::getYeWuId, id)
                .list();
        chuanYuanDiaoLingVO.setLiuChengYeWuList(liuChengYeWuList);
        return chuanYuanDiaoLingVO;
    }


    /**
     * 流程审批操作
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean shenPi(LiuChengYeWuSavePO savePO){
        Long id = savePO.getId();
        if (id == null) {
            throw new RuntimeException("id不能为空");
        }
        if (savePO.getJieDianCaoZuo().equals("同意") || savePO.getJieDianCaoZuo().equals("拒绝")) {
        } else {
            throw new RuntimeException("节点操作参数值只能是`同意`或`拒绝`");
        }
        LiuChengYeWuDO liuChengYeWuDO = liuChengYeWuService.getById(id);
        if (liuChengYeWuDO == null) {
            throw new RuntimeException("流程对象数据不能为空");
        }
        if ("是".equals(liuChengYeWuDO.getShiFouShenPi())) {
            throw new RuntimeException("该节点已有人审批，请刷新数据查看");
        }

        LiuChengYeWuDO liuChengYeWuDOUpdate = new LiuChengYeWuDO();
        liuChengYeWuDOUpdate.setId(id);
        liuChengYeWuDOUpdate.setShenPiRen(UserThreadLocal.get().getUsername());
        liuChengYeWuDOUpdate.setJieDianCaoZuo(savePO.getJieDianCaoZuo());   //节点操作。 同意/拒绝
        liuChengYeWuDOUpdate.setShenPiYiJian(savePO.getShenPiYiJian());     //审批意见
        liuChengYeWuDOUpdate.setShiFouShenPi("是");                         //该节点是否已有人审批
        if ("同意".equals(savePO.getJieDianCaoZuo()) && "是".equals(liuChengYeWuDO.getShiFouZuiHouJieDian())) {
            //船员调令数据修改状态
            this.lambdaUpdate()
                    .set(ChuanYuanDiaoLingDO::getShenPiZhuangTai,"审批通过")
                    .eq(ChuanYuanDiaoLingDO::getId,liuChengYeWuDO.getYeWuId())
                    .update();
            liuChengYeWuDOUpdate.updateById();
            liuChengYeWuService.lambdaUpdate()
                    .set(LiuChengYeWuDO::getShenPiZhuangTai,"审批通过")
                    .eq(LiuChengYeWuDO::getYeWuId,liuChengYeWuDO.getYeWuId())
                    .update();
        }
        if ("拒绝".equals(savePO.getJieDianCaoZuo())) {
            //离船申请数据修改状态
            this.lambdaUpdate()
                    .set(ChuanYuanDiaoLingDO::getShenPiZhuangTai,"审批拒绝")
                    .eq(ChuanYuanDiaoLingDO::getId,liuChengYeWuDO.getYeWuId())
                    .update();
            liuChengYeWuDOUpdate.updateById();
            liuChengYeWuService.lambdaUpdate()
                    .set(LiuChengYeWuDO::getShenPiZhuangTai,"审批拒绝")
                    .eq(LiuChengYeWuDO::getYeWuId,liuChengYeWuDO.getYeWuId())
                    .update();
        }

        /*找到船员调配的数据*/
        return true;
    }









}
